
<h1>Canvas Gradients</h1>
<h2>Radial Gradients</h2>
<em>MDN example</em><br>
<canvas id="mdnRadial" width="200" height="200"></canvas><br>
<em>Balls (transparent end stops)</em><br>
<canvas id = "balls"></canvas>
<h3>Interactive Radial Gradients (mouse over)</h3>
<hr>
<em>A radial gradient</em><br>
<canvas id="radialHell1" width="400" height="300"></canvas>
<br>
<hr>
<em>An inverted radial gradient (start circle larger than end circle)</em><br>
<canvas id="radialHell2" width="400" height="300"></canvas>

<h2>Conic Gradients</h2>
<canvas id="conic" width="200" height="200"></canvas>
<h2>Linear Gradients</h2>
<em>This time in a path to spice things up!</em><br>
<canvas id="linear" width="400" height="200"></canvas>

<script>
{
  // MDN radial gradient example
  const canvas = document.getElementById("mdnRadial");
  const ctx = canvas.getContext("2d");

  const gradient = ctx.createRadialGradient(110, 90, 30, 100, 100, 70);

  gradient.addColorStop(0, "pink");
  gradient.addColorStop(0.9, "white");
  gradient.addColorStop(1, "green");

  ctx.fillStyle = gradient;
  ctx.fillRect(20, 20, 160, 160);
}
</script>
<script>
{
  const canvas = document.getElementById('balls');
  var ctx = canvas.getContext('2d');

  const radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
  radgrad.addColorStop(0, '#A7D30C');
  radgrad.addColorStop(0.9, '#019F62');
  radgrad.addColorStop(1, 'rgba(1,159,98,0)');

  const radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
  radgrad2.addColorStop(0, '#FF5F98');
  radgrad2.addColorStop(0.75, '#FF0188');
  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');

  const radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
  radgrad3.addColorStop(0, '#00C9FF');
  radgrad3.addColorStop(0.8, '#00B5E2');
  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');

  const radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
  radgrad4.addColorStop(0, '#F4F201');
  radgrad4.addColorStop(0.8, '#E4C700');
  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');

  ctx.fillStyle = radgrad4;
  ctx.fillRect(0,0,150,150);

  ctx.fillStyle = radgrad3;
  ctx.fillRect(0,0,150,150);

  ctx.fillStyle = radgrad2;
  ctx.fillRect(0,0,150,150);

  ctx.fillStyle = radgrad;
  ctx.fillRect(0,0,150,150);
}
</script>
<script>
// Interactive radial gradients... The MacDue debugging experience live!

const makeMouseDemo = (canvasId, body) => {
  const canvas = document.getElementById(canvasId);
  const ctx = canvas.getContext("2d");
  const mouse = { x: 0, y: 0 };
  let lastMouse = mouse;
  const mouseEvent = (e) => { mouse.x = e.offsetX; mouse.y = e.offsetY }
  canvas.addEventListener("mousemove", mouseEvent);
  body(canvas, ctx, canvas.width/2, canvas.height/2);
  const loop = () => {
    if (mouse.x != lastMouse.x || mouse.y != lastMouse.y)
      body(canvas, ctx, mouse.x, mouse.y);
    lastMouse = { ...mouse };
    requestAnimationFrame(loop);
  };
  requestAnimationFrame(loop);
}

makeMouseDemo("radialHell1", (canvas, ctx, mX, mY) => {
  var grd = ctx.createRadialGradient(mX, mY, 10, canvas.width/2, canvas.height/2, 100);
  grd.addColorStop(0, "red");
  grd.addColorStop(0.4, "purple");
  grd.addColorStop(1, "cyan");
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
})

makeMouseDemo("radialHell2", (canvas, ctx, mX, mY) => {
  var grd = ctx.createRadialGradient(mX, mY, 100, canvas.width/2, canvas.height/2, 10);
  grd.addColorStop(0, "pink");
  grd.addColorStop(0.6, "blue");
  grd.addColorStop(1, "orange");
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = grd;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
})
</script>
<script>
{
  const canvas = document.getElementById("conic");
  const ctx = canvas.getContext("2d");

  const gradient = ctx.createConicGradient(0, 100, 100);

  gradient.addColorStop(0, "red");
  gradient.addColorStop(0.25, "orange");
  gradient.addColorStop(0.5, "yellow");
  gradient.addColorStop(0.75, "green");
  gradient.addColorStop(1, "blue");

  ctx.fillStyle = gradient;
  ctx.fillRect(20, 20, 200, 200);
}
</script>
<script>
{
  const canvas = document.getElementById("linear");
  const ctx = canvas.getContext("2d");

  const gradient = ctx.createLinearGradient(20, 20, 220, 120);
  gradient.addColorStop(0,"red");
  gradient.addColorStop(0.15,"yellow");
  gradient.addColorStop(0.3,"green");
  gradient.addColorStop(0.45,"aqua");
  gradient.addColorStop(0.6,"blue");
  gradient.addColorStop(0.7,"fuchsia");
  gradient.addColorStop(1,"red");

  ctx.fillStyle = gradient;

  const gradient2 = ctx.createLinearGradient(200,0,400,50);
  gradient2.addColorStop(0,"cyan");
  gradient2.addColorStop(1,"fuchsia");

  ctx.strokeStyle = gradient2;

  const starPath = (cx, cy, spikes, outerRadius, innerRadius) => {
    let x = cx;
    let y = cy;
    let rot = Math.PI / 2 * 3;
    const step = Math.PI / spikes;

    ctx.beginPath();
    ctx.moveTo(cx, cy - outerRadius)
    for (i = 0; i < spikes; i++) {
      x = cx + Math.cos(rot) * outerRadius;
      y = cy + Math.sin(rot) * outerRadius;
      ctx.lineTo(x, y)
      rot += step

      x = cx + Math.cos(rot) * innerRadius;
      y = cy + Math.sin(rot) * innerRadius;
      ctx.lineTo(x, y)
      rot += step
    }
    ctx.lineTo(cx, cy - outerRadius);
    ctx.closePath();
  }

  starPath(canvas.width/4,canvas.height/2,5,100,60);
  ctx.fill();

  starPath(canvas.width/4 + 200 ,canvas.height/2,5,80,40);
  ctx.lineWidth = 5;
  ctx.stroke();
}
</script>
